package com.nuanshui.heatedloan.credit.pay;

import com.aipg.acquery.AcNode;
import com.aipg.acquery.AcQueryRep;
import com.aipg.acquery.AcQueryReq;
import com.aipg.common.AipgReq;
import com.aipg.common.InfoReq;
import com.allinpay.XmlTools;
import com.nuanshui.framework.lang.SysStringUtils;
import com.nuanshui.framework.springContext.SpringContextUtil;
import com.nuanshui.heatedloan.credit.facade.CreditConvertService;
import com.nuanshui.heatedloan.credit.facade.MerInfoService;
import com.nuanshui.heatedloan.credit.pay.utils.AllinPayUtil;
import com.nuanshui.heatedloan.credit.vo.MerInfoVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.net.URLDecoder;
import java.util.List;
import java.util.concurrent.Callable;

@Service
public class AllinPayAccountMgr {

    private Logger logger = LoggerFactory.getLogger(AllinPayAccountMgr.class);

    @Autowired
    private CreditConvertService creditConvertService;

    @Autowired
    private MerInfoService merInfoService;

    private List<InfoReq> accountList;

    public InfoReq selectAccount(PayRequest request)
    {
        InfoReq info=getDefaultAccount();
        return info;
    }

    public InfoReq getDefaultAccount() {
        InfoReq info=new InfoReq();
        MerInfoVO merInfoVO= merInfoService.loadDefaultMerInfo();
        if (merInfoVO != null){
            info.setMERCHANT_ID(merInfoVO.getMerChantId());
            info.setREQ_SN(AllinPayUtil.getReqSn(merInfoVO.getMerChantId()));
            info.setUSER_NAME(merInfoVO.getUserName());
            info.setUSER_PASS(merInfoVO.getUserPassword());
            info.setLEVEL(merInfoVO.getLevel());
            info.setDATA_TYPE(merInfoVO.getDataType());
            info.setVERSION(merInfoVO.getVersion());
        }
        return info;
    }

    /**
     * 报文签名
     * @param xml
     * @return
     * @throws Exception
     */
    public String signMsg(String xml) throws Exception{
            MerInfoVO merInfoVO= merInfoService.loadDefaultMerInfo();
            if (merInfoVO != null){
                logger.info("-----私有证书路径："+merInfoVO.getPfxPath());
                logger.info("-----私有证书密码："+merInfoVO.getPfxPassword());
                String path= URLDecoder.decode(AllinPayAccountMgr.class.getClassLoader().getResource(merInfoVO.getPfxPath()).toURI().getPath(),"utf-8");
                xml= XmlTools.signMsg(xml,path,merInfoVO.getPfxPassword(), false);
            }
            return xml;
    }

    public AipgReq createReq()
    {
        return createReq(null);
    }

    public AipgReq createReq(PayRequest request)
    {
        AipgReq aipgReq = new AipgReq();
        //组装报文头部信息
        InfoReq info = null;

        if(request==null)
        {
            info=getDefaultAccount();
        }
        else
        {
            info=selectAccount(request);
        }
        aipgReq.setINFO(info);
        return aipgReq;
    }

    private List<AcNode> internalGetAcNode(final String acctNo)
    {

        AllinPayTool tool= SpringContextUtil.getBean(AllinPayTool.class);

        AcQueryRep rep=null;

        PayContext context=tool.execute(TransRequestCode.TRX_CODE_QUERY_ACCOUNT, new Callable<AcQueryReq>() {

            @Override
            public AcQueryReq call() throws Exception {

                AcQueryReq req = new AcQueryReq();
                req.setACCTNO(acctNo);
                return req;
            }
        });

        if(context!=null)
        {
            rep=context.getData();

            if(rep!=null)
            {
                return rep.getDetails();
            }
        }

        return null;
    }

    public AcNode getAcNode(String acctNo) {

        if(SysStringUtils.isEmpty(acctNo))
            return null;

        List<AcNode> list = internalGetAcNode(acctNo);

        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }

        return null;
    }

    public List<AcNode> getAcNodes()
    {
        return internalGetAcNode(null);
    }

}
